/*
 * OptionsModel.java
 *
 * @author Michael Hansen
 * @author Lukas Thuernagel
 * @author Soeren Warszus
 */

package risk.options;

import risk.player.PlayerModel;
import risk.io.LoadMap;
import risk.game.*;
import risk.card.*;
import java.io.File;
import java.util.*;
import java.awt.Color;

public class OptionsModel {
    /**
     * Der verwendete OpionsView
     */
    private OptionsView view;
    
    /**
     * Die ausgewaehlte Spielkarte.
     */
    private String selectedMap = null;
    
    /**
     * PFad zu den Skriptdateien und Grafiken
     */
    private String path;
    
    /**
     * Es sind 6 moeglicher Spieler. Array beinhaltet alle 
     * teilnehmenden Spieler
     */
    private ArrayList<PlayerModel> playerModels;
    
    /**
     * Das einzige RiskModel
     */
    private RiskModel riskModel;
   
    /**
     * Das zum RiskModel zugehoerige View
     */
    private Board board;
    
    /**
     * Die WorldMap mit allen territories und continents
     */
    private WorldMap worldMap;
    
    /**
     * Der verwendete Kartenstapel
     */
    private Deck deck;
    
    /** 
     * Erzeugt ein neues OptionsModel
     */
    public OptionsModel() {
    }
 
    /**
     * Methode zum erzeugen der Spieler 1-6
     * Methode kann geloescht werden, wenn die 
     * dynamische Erzeugung von Objekten funktioniert
     */
    private void initializePlayer(Map<String, Color> playerList){
        playerModels = new ArrayList();
        
        for (Map.Entry<String, Color> map : playerList.entrySet()) {
            PlayerModel player = new PlayerModel(map.getKey(),
                                                 map.getValue());
            player.setState(0);
            PlayerCard pc = new PlayerCard(player);
            PlayerCardView pcv = new PlayerCardView(pc);
            player.registerPlayerCardView(pc,pcv);
            this.playerModels.add(player);
        }
        java.util.Collections.shuffle(this.playerModels);
    }
    
    /**
     * Rueckgabe der Namen der Maps als String
     *
     * @return String[] Array, das die Namen der Maps beinhaltet
     */
    public String[] getMapNames() 
    {
        this.path = System.getProperty("java.class.path") + "/risk/maps/";
        //this.path = "/home/swa/Desktop/maps/";

        File mapDir = new File(this.path);
        String[] mapList = mapDir.list(new MapFilenameFilter()); 
        this.selectedMap = mapList[0]; 

        return mapList;
    }
     
    /**
     * Setzt die Spielkarte.
     *
     * @param map Die Spielkarte als String.
     */
    public void setSelectedMap(String map) 
    {
        this.selectedMap = map;
    }
    
    /**
     * Erfragt die aktuell gesetze Spielkarte.
     *
     * @return Die Spielkarte als String.
     */
    public String getSelectedMap() 
    {
        return this.selectedMap;
    }
    
     /**
     * Die Methode registriert einen View beim Model. 
     *
     * @param view  Der zu registrierende OptionsView.
     */
    public void registerView (OptionsView optionsView) 
    {
        this.view = optionsView;
    }
    
    
    /**
     *
     */
    public void validate() {
        boolean sameColor = false;
        ArrayList colors = new ArrayList();
        
        Map<String, Color> player = this.view.getPlayer();
        
        for (Map.Entry<String, Color> map : player.entrySet()) {
            if (colors.contains(map.getValue())) {
                sameColor = true;
                break;
            }
           
            colors.add(map.getValue());
        }
        
        System.out.println(this.view.sameName);
        
        if (player.size() < 2) { 
            this.view.throwError("Es muessen mindestens 2 Spieler am Spiel teilnehmen!");
        } else if (sameColor) { 
            this.view.throwError("Mindestens 2 Spieler besitzen die gleiche Spielfarbe!");   
        } else if (this.view.sameName) {
            this.view.throwError("Mindestens 2 Spieler besitzen den gleichen Spielernamen!"); 
        } else {
            this.initilializeGame(player);
            this.view.setVisible(false);
        }
    }
    
    
    /**
     * Initialisierung des Spiels anhand der vorgenommenen Einstellungen
     */
    public void initilializeGame(Map<String, Color> pl) 
    {
        // Skriptdatei laden
        LoadMap loadMap = new LoadMap(this.path + this.selectedMap);
        
        // erzeugte Instanz von WorldMap abfragen
        worldMap = loadMap.getWorldMap();
        
        //Anlegen der Spieler
        Map<String, Color> playerList = pl;

        //Deck anlegen
        deck = new Deck();
        ArrayList<Territory> alTerritories = worldMap.getTerritories();
        //Karten hinzufuegen
        //Zaehler damit die Symbole gleichverteilt werden
        int count = 1;
        //Zufallszahlen zum Einfuegen der 'Joker'
        //int random1 = new Random().nextInt(alTerritories.size()/2);
        //int random2 = new Random().nextInt(alTerritories.size()/2)+alTerritories.size();
        for(int i=0; i<alTerritories.size();i++){
           // boolean isFullOfJoker = false;
            String symbol = "";
            String symbolInfanterie = "Infanterie";
            String symbolKavallerie = "Kavallerie";
            String symbolArtillerie = "Artillerie";
            if(count==1){
                symbol = symbolInfanterie;
                count++;
            }
            else if(count==2){
                symbol = symbolKavallerie;
                count++;
            }
            else if(count==3){
                symbol = symbolArtillerie;
                count = 1;
            }
            Card newCard = new Card(alTerritories.get(i),symbol);
            CardView cv = new CardView(newCard);
            deck.insert(newCard);
        }
        initializePlayer(playerList);
        //Territories den Player zuweisen
        Deck tmp = new Deck();
        //tmp.changeDeck(deck.getDeck());
        //tmp.shuffle();
        deck.shuffle();
        int s = 1;
        count = 0;
        for(int i=0;i<alTerritories.size();i++){
            if(count>=playerModels.size()){
                count =0;
            }
            Card c = deck.takeFirst();
            tmp.insert(c);
            c.getTerritory().initializeArmySize(1);
            //if(c.getSymbol().compareTo("Joker")!=0){
            this.playerModels.get(count).setTerritory(c.getTerritory());
            count++;
            //}
        }
        for(int j=0; j<alTerritories.size();j++){
            deck.insert(tmp.takeFirst());
        }
        Card j1 = new Card(null, "Joker");
        CardView cv1 = new CardView(j1);
        Card j2 = new Card(null, "Joker");
        CardView cv2 = new CardView(j2);
        deck.insert(j1);
        deck.insert(j2);
        //RiskModel und das Spielbrett Board anlegen
        riskModel = new RiskModel(worldMap,playerModels,deck);
        board = new Board(riskModel);
    }
}
